# To change this template, choose Tools | Templates
# and open the template in the editor.

__author__="joepearson"
__date__ ="$May 2, 2011 7:42:34 PM$"

import sys
from PyQt4 import QtGui
from PyQt4 import QtCore
from OSC import OSCClient
from OSC import OSCMessage
from OSC import OSCServer
import socket

global debug
debug = True

class MainWindow(QtGui.QWidget):

    def __init__(self):
        super(MainWindow, self).__init__()

        # Data types
        self.dataTypes = ['Integer', 'Float', 'String', 'OSC Blob']

        # Initialise the UI
        self.initUI()


    def initUI(self):

        # Create all the UI elements.

        # Sending elements
        self.destLabel = QtGui.QLabel('Destination')
        self.portLabel = QtGui.QLabel('Port')
        self.oscAddrLabel = QtGui.QLabel('OSC Address')
        self.dataLabel = QtGui.QLabel('Data')
        self.payLoadLabel = QtGui.QLabel('Payload')

        self.destEdit = QtGui.QLineEdit()
        self.portEdit = QtGui.QLineEdit()
        self.oscAddrEdit = QtGui.QLineEdit()
        self.dataCombo = QtGui.QComboBox(self)
        self.payLoadEdit = QtGui.QLineEdit()
        self.sendBtn = QtGui.QPushButton('Send', self)
        

        # Receive elements
        self.ipAddressLabel = QtGui.QLabel('Local IP Address')
        self.recvPortLabel = QtGui.QLabel('Port')
        self.logLabel = QtGui.QLabel('Log')

        self.ipAddressEdit = QtGui.QLineEdit()
        self.recvPortEdit = QtGui.QLineEdit()
        self.logEdit = QtGui.QTextEdit()
        # Add items to the combo box.

        for dataType in self.dataTypes:
            self.dataCombo.addItem(dataType)

        # Create the send grid layout object.
        self.sendGrid = QtGui.QGridLayout()
        self.sendGrid.setSpacing(10)

        # Add widgets to the send Group Box.
        self.sendGrid.addWidget(self.destLabel, 1, 0)
        self.sendGrid.addWidget(self.destEdit, 1, 1)

        self.sendGrid.addWidget(self.portLabel, 2, 0)
        self.sendGrid.addWidget(self.portEdit, 2, 1)

        self.sendGrid.addWidget(self.oscAddrLabel, 3, 0)
        self.sendGrid.addWidget(self.oscAddrEdit, 3, 1)

        self.sendGrid.addWidget(self.dataLabel, 4, 0)
        self.sendGrid.addWidget(self.dataCombo, 4, 1)

        self.sendGrid.addWidget(self.payLoadLabel, 5, 0)
        self.sendGrid.addWidget(self.payLoadEdit, 5, 1)

        self.sendGrid.addWidget(self.sendBtn, 5, 0, 5, 2)

        # Create the received group box

        self.recvGrid = QtGui.QGridLayout()
        self.recvGrid.setSpacing(10)

        # Add widgets to the recv Group box.
        self.recvGrid.addWidget(self.ipAddressLabel, 1, 0)
        self.recvGrid.addWidget(self.ipAddressEdit, 1, 1)

        self.recvGrid.addWidget(self.recvPortLabel, 2, 0)
        self.recvGrid.addWidget(self.recvPortEdit, 2, 1)

        self.recvGrid.addWidget(self.logLabel, 3, 0)
        self.recvGrid.addWidget(self.logEdit, 4,0,5,0)

        # Connections

        # Send OSC button
        self.connect(self.sendBtn, QtCore.SIGNAL('clicked()'),
            self.sendOSC)

        # Every time listen IP or port are changed, update internally.
        self.connect(self.recvPortEdit, QtCore.SIGNAL('textChanged(QString)'),
            self.recvListenChanged)
        #self.connect(self.ipAddressEdit, QtCore.SIGNAL('textChanged(QString)'),
        #    self.recvListenChanged)

        # Add some default values
        self.destEdit.setText('127.0.0.1')
        self.portEdit.setText('10000')
        self.oscAddrEdit.setText('/test')
        self.payLoadEdit.setText('999999')

        self.recvPortEdit.setText('10000')
        self.ipAddressEdit.setText(self.currentIP())


        # Layouts
        sendGroupBox = QtGui.QGroupBox()
        recvGroupBox = QtGui.QGroupBox()

        sendGroupBox.setTitle('Send OSC')
        recvGroupBox.setTitle('Receive OSC')

        sendGroupBox.setLayout(self.sendGrid)
        recvGroupBox.setLayout(self.recvGrid)


        hLayout = QtGui.QHBoxLayout()
        hLayout.setStretch(1,1)
        hLayout.addWidget(sendGroupBox)
        #hLayout.addWidget(recvGroupBox)


        self.setLayout(hLayout)

        # Window title
        self.setWindowTitle("OSC Tester")

        # Prevent user resize
        self.resize(600,300)
        self.setFixedSize(self.size().width(), self.size().height())

    def sendOSC(self):
        """
        Send out some OSC using the values taken from the UI.
        """

        destHost = str(self.destEdit.displayText())
        destPort = int(self.portEdit.displayText())
        address = self.oscAddrEdit.displayText()
        type = self.dataCombo.currentText()
        payload = self.payLoadEdit.displayText()

        # TODO validate this data.

        oscClient = OSCClient()
        oscClient.connect((destHost,destPort))

        msg = OSCMessage(address)

        if type == "Integer":
            msg.append(int(payload), "i")
        elif type == "Float":
            msg.append(float(payload), "f")
        elif type == "String":
            msg.append(str(payload), "s")
        elif type == "OSC Blob":
            msg.append(0b001100, "b")

        try:
            oscClient.send(msg)
        except Exception:
            print Exception
        

        if debug:
            print "Sending OSC\nDestination: %s:%i, Address: %s, Type:%s" %\
                (destHost, destPort, address, type)

    def currentIP(self):
        """
        Return the current IP address.
        """
        # Obtain a sensible IP address to bind to.
        ipAddress = socket.gethostbyname(socket.gethostname())

        # If socket.gethostbyname() fails for some reason, choose loopback interface
        # I.e localhost.
        if not ipAddress:
            ipAddress = "127.0.0.1"

        return ipAddress

    def recvListenChanged(self, newPort):

        # TODO fix up server.

        newPort = int(newPort)
        ipAddress = str(self.ipAddressEdit.displayText()) or self.currentIP()

#        if not self.oscServer:
#            try:
#                self.oscServer = OSCServer((ipAddress, newPort))
#            except:
#                pass

        if debug:
            print "Listening: %s:%i" % (ipAddress, newPort)






if __name__ == "__main__":
    # Run the app.

    app = QtGui.QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())
    
